package com.gzj.environment.framework.util;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.TimeZone;

public class ConcurrentUtil {
    /** 锁对象 */
    private static final Object lockObj = new Object();
    /** 存放不同的日期模板格式的sdf的Map */
    private static Map<String, ThreadLocal<SimpleDateFormat>> sdfMap = new HashMap<>();
    /** 时间的默认格式 */
    public static final String DEFAULT_PATTERN = "yyyy-MM-dd HH:mm:ss";

    /**
     * 返回一个ThreadLocal的sdf,每个线程只会new一次sdf
     *
     * @param pattern
     * @return
     */
    private static SimpleDateFormat getSdf(final String pattern) {
        ThreadLocal<SimpleDateFormat> tl = sdfMap.get(pattern);
        // 此处的双重判断和同步是为了防止sdfMap这个单例被多次put重复的sdf
        if (tl == null) {
            synchronized (lockObj) {
                tl = sdfMap.get(pattern);
                if (tl == null) {
                    // 只有Map中还没有这个pattern的sdf才会生成新的sdf并放入map
                    System.out.println("put new sdf of pattern " + pattern + " to map");
                    // 这里是关键,使用ThreadLocal<SimpleDateFormat>替代原来直接new SimpleDateFormat
                    tl = new ThreadLocal<SimpleDateFormat>() {
                        @Override
                        protected SimpleDateFormat initialValue() {
                            System.out.println("thread: " + Thread.currentThread() + " init pattern: " + pattern);
                            return new SimpleDateFormat(pattern);
                        }
                    };
                    sdfMap.put(pattern, tl);
                }
            }
        }
        return tl.get();
    }
    /**
     * 线程安全的格式化日期对象（使用默认格式"yyyy-MM-dd HH:mm:ss"）
     * @author tsing
     * @date 2020年12月9日
     * @param date 日期对象
     * @return
     */
    public static String format(Date date) {
        return ConcurrentUtil.format(date, DEFAULT_PATTERN);
    }

    /**
     * 线程安全的格式化日期对象（使用指定格式）
     * @author tsing
     * @date 2020年12月9日
     * @param date 日期对象
     * @param pattern 指定格式
     * @return
     */
    public static String format(Date date, String pattern) {
        return getSdf(pattern).format(date);
    }


    /**
     * 线程安全的解析日期对象（使用默认格式"yyyy-MM-dd HH:mm:ss"）
     * @author tsing
     * @date 2020年12月9日
     * @param dateStr 日期字符串
     * @return
     * @throws Exception
     */
    public static Date parse(String dateStr) {
        try {
            return ConcurrentUtil.parse(dateStr, DEFAULT_PATTERN);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 线程安全的解析日期对象（使用指定格式）
     * @author tsing
     * @date 2020年12月9日
     * @param dateStr 日期字符串
     * @param pattern 指定格式
     * @return
     * @throws Exception
     */
    public static Date parse(String dateStr, String pattern) {
        try {
            return getSdf(pattern).parse(dateStr);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

}
